﻿using System;
using System.Collections.Generic;
using AMS.DataAccess.Common;
using AMS.DataAccess.Sql;
using AMS.DataAccess.Trademark.BO;
using AMS.DataAccess.Trademark.BO.Enums;
using AMS.DataAccess.Trademark.Filters;
using AMS.DataAccess.Trademark.Interfaces;
using AMS.DataAccess.BO;
using System.Data;

namespace AMS.DataAccess.Trademark
{
    public class TaskManager : ITaskManager
    {
        public List<TaskInfo> GetTaskList(CallContext context, TaskFilter filter)
        {
            SqlBuilder sql = new SqlBuilder();
            sql.Add("SELECT t.*");
            sql.Add("      ,c.CaseIndex");
            sql.Add("FROM TT_Task t");
            sql.Add("LEFT JOIN VT_Case c ON t.CaseID = c.AID");
            sql.Add("WHERE 1=1");
            if (filter != null)
            {
                ApplyTaskFilter(sql, filter);
            }

            AMS.DataAccess.SqlDebugger.WriteLine(sql);

            var ds = SqlDBHelper.Query(sql.ToString());
            var list = BusinessObjectMapping.DataTableToBOList<TaskInfo>(ds.Tables[0]);
            return list;
        }

        public List<TaskInfo> GetPagedTaskList(CallContext context, TaskFilter filter, int pageIndex, int pageSize)
        {
            int total;
            return GetPagedTaskList(context, filter, pageIndex, pageSize, false, out total);
        }

        public List<TaskInfo> GetPagedTaskList(CallContext context, TaskFilter filter, int pageIndex, int pageSize, out int totalCount)
        {
            return GetPagedTaskList(context, filter, pageIndex, pageSize, true, out totalCount);
        }

        private List<TaskInfo> GetPagedTaskList(CallContext context, TaskFilter filter, int pageIndex, int pageSize, bool caculateTotal, out int totalCount)
        {
            SqlBuilder sql = new SqlBuilder();
            sql.Add("SELECT t.*");
            sql.Add("      ,c.CaseIndex");
            sql.Add("FROM TT_Task t");
            sql.Add("LEFT JOIN VT_Case c ON t.CaseID = c.AID");
            sql.Add("WHERE 1=1");
            if (filter != null)
            {
                ApplyTaskFilter(sql, filter);
            }

            AMS.DataAccess.SqlDebugger.WriteLine(sql);

            SqlInfo sqlInfo = new SqlInfo();
            sqlInfo.BaseSql = sql.ToString();
            sqlInfo.PKField = "AID";

            PagedSqlInfo pagedSql = new PagedSqlInfo();
            PagerWrapper.WrapSql(sqlInfo, new PagerInfo(pageIndex, pageSize), ref pagedSql);


            System.Diagnostics.Debug.WriteLine(pagedSql.PagedSql);

            var ds = SqlDBHelper.Query(pagedSql.PagedSql);
            var list = BusinessObjectMapping.DataTableToBOList<TaskInfo>(ds.Tables[0]);
            if (caculateTotal)
            {
                var totalDS = SqlDBHelper.Query(pagedSql.TotalCountSql);
                totalCount = AdoConverter.ToInt32(totalDS.Tables[0].Rows[0][0]);
            }
            else
            {
                totalCount = 0;
            }

            return list;
        }

        void ApplyTaskFilter(SqlBuilder sql, TaskFilter filter)
        {
            if (!filter.QueryClosedTask)
            {
                sql.Add("    AND ", new SqlCondition("t.Status", (int)TaskStatus.Closed, SqlOperations.LessThan));
            }
            if (filter.OwnerID != 0)
            {
                sql.Add("    AND t.OwnerID = ", filter.OwnerID.ToString());
            }
            if (filter.CaseID != 0)
            {
                sql.Add("    AND t.OwnerID = ", filter.OwnerID.ToString());
            }
            if (filter.TaskName != null)
            {
                sql.Add("    AND t.TaskName", filter.TaskName.ToString());
            }
            if (filter.StatusList.Count > 0)
            {
                sql.Add("    AND ", new SqlEnumConditionList<TaskStatus>("t.Status", filter.StatusList));
            }
            if (filter.Priorities.Count > 0)
            {
                sql.Add("    AND ", new SqlEnumConditionList<TaskPriority>("t.Priority", filter.Priorities));
            }
            if (filter.CaseIndex != null)
            {
                sql.Add("    AND c.CaseIndex", filter.CaseIndex.ToString());
            }
            if (filter.StartDate != null)
            {
                string sqlFormat = filter.StartDate.ToString();
                sql.Add("    AND ", string.Format(sqlFormat, "StartDateTime"));
            }
        }

        public TaskInfo GetTask(CallContext context, int taskId)
        {
            SqlBuilder sql = new SqlBuilder();
            sql.Add("SELECT *");
            sql.Add("FROM TT_Task");
            sql.Add("WHERE ", new SqlCondition("AID", taskId));
            var ds = SqlDBHelper.Query(sql.ToString());
            if (ds.Tables[0].Rows.Count > 0)
            {
                var task = BusinessObjectMapping.DataRowToBO<TaskInfo>(ds.Tables[0].Rows[0]);
                return task;
            }
            else
            {
                return null;
            }
        }

        public bool BatchAddTasks(CallContext context, List<TaskInfo> tasks)
        {
            if (tasks.Count > 0)
            {
                SqlBatch batch = new SqlBatch();
                foreach (TaskInfo task in tasks)
                {
                    SqlInsert insert = batch.CreateSqlInsert("TT_Task");
                    insert.AddBusinessObject(task);
                }

                return 0 < SqlDBHelper.ExecuteSql(batch.ToString());
            }
            else
            {
                return true;
            }
        }

        public List<TaskInfo> GetNewCaseTasks(CallContext context, TaskFilter filter)
        {
            SqlBuilder sql = new SqlBuilder();
            sql.Add("SELECT DISTINCT");
            sql.Add("    t.AID");
            sql.Add("    ,t.TaskName");
            sql.Add("FROM TT_Task t");
            sql.Add("LEFT JOIN (");
            sql.Add("        SELECT DISTINCT r.AID AS RFID");
            sql.Add("        FROM TT_RecvFile r");
            sql.Add("        INNER JOIN TTD_RF dr ON r.RFIndex=dr.RFIndex");
            sql.Add("        WHERE dr.Type='Y'");
            sql.Add("    )r ON t.RefRFID = r.RFID");
            sql.Add("WHERE 1=1");
            if (filter != null)
            {
                if (filter.OwnerID != 0)
                {
                    sql.Add("    AND OwnerID = ", filter.OwnerID.ToString());
                }
                if (filter.StatusList.Count > 0)
                {
                    var condList = new SqlEnumConditionList<TaskStatus>("Status", filter.StatusList);
                    sql.Add("    AND ", condList.ToString());
                }
            }

            sql.Add("    AND t.RefRFID IS NOT NULL");
            sql.Add("    AND t.TaskName LIKE '新建%'");

            AMS.DataAccess.SqlDebugger.WriteLine(sql);

            var ds = SqlDBHelper.Query(sql.ToString());
            var list = BusinessObjectMapping.DataTableToBOList<TaskInfo>(ds.Tables[0]);
            return list;
        }

        public CustomerInfo GetTaskCustomer(CallContext context, int taskId)
        {
            SqlBuilder sql = new SqlBuilder();
            sql.Add("SELECT DISTINCT c.AID, c.Name");
            sql.Add("FROM TT_Task t,");
            sql.Add("TT_RecvFile r,");
            sql.Add("TC_Customer c");
            sql.Add("WHERE t.RefRFID = r.AID");
            sql.Add("AND r.CustomerID = c.AID");
            sql.Add("AND t.AID = ", taskId.ToString());

            AMS.DataAccess.SqlDebugger.WriteLine(sql);

            var ds = SqlDBHelper.Query(sql.ToString());
            if (ds.Tables[0].Rows.Count > 0)
            {
                return BusinessObjectMapping.DataRowToBO<CustomerInfo>(ds.Tables[0].Rows[0]);
            }
            else
            {
                return null;
            }
        }

        /// <summary>
        /// 获取任务对于状态数的统计。
        /// 列：Status, StatusCount
        /// </summary>
        /// <param name="context"></param>
        /// <param name="includeClosedTasks"></param>
        /// <returns></returns>
        public DataTable GetMyTaskSummaryByStatus(CallContext context, bool includeClosedTasks)
        {
            SqlBuilder sql = new SqlBuilder();
            sql.Add("select [Status], COUNT(Status) AS StatusCount");
            sql.Add("from TT_Task");
            sql.Add("where 1=1");
            // TODO: Enable user here
            //sql.Add("    AND OwnerID = ", context.UserID.ToString());
            if (!includeClosedTasks)
            {
                sql.Add("    AND ", new SqlCondition("[Status]", (int)TaskStatus.Closed, SqlOperations.LessThan));
            }

            sql.Add("group by [Status]");

            AMS.DataAccess.SqlDebugger.WriteLine(sql);

            var ds = SqlDBHelper.Query(sql.ToString());
            return ds.Tables[0];
        }

        public bool UpdateTask(CallContext context, TaskInfo task)
        {
            if (task.ModifyDateTime == DateTime.MinValue)
            {
                task.ModifyDateTime = DateTime.Now;
            }
            if (task.ModifyUserID == 0)
            {
                // TODO: enable user id here
                // task.ModifyUserID = context.UserID;
            }

            SqlUpdate update = new SqlUpdate("TT_Task");
            update.AddBusinessObject(task);
            update.AddCondition(new SqlCondition("AID", task.AID));

            AMS.DataAccess.SqlDebugger.WriteLine(update);

            return 0 < SqlDBHelper.ExecuteSql(update.ToString());
        }

        public int BatchChangeTaskStatus(CallContext context, int[] taskIds, TaskStatus targetStatus)
        {
            return BatchChangeTaskStatus(context, taskIds, targetStatus, null);
        }

        public int BatchChangeTaskStatus(CallContext context, int[] taskIds, TaskStatus targetStatus, TaskStatus[] prevStatusList)
        {
            if (taskIds == null || taskIds.Length == 0)
            {
                return 0;
            }

            SqlConditionList prevStatusCondition = null;
            if (prevStatusList != null && prevStatusList.Length > 0)
            {
                prevStatusCondition = new SqlEnumConditionList<TaskStatus>("Status", prevStatusList);
            }

            DateTime now = DateTime.Now;
            SqlBatch batch = new SqlBatch();
            foreach (int taskId in taskIds)
            {
                var update = batch.CreateSqlUpdate("TT_Task");
                update.AddColumn("Status", (int)targetStatus);
                update.AddColumn("ModifyDateTime", now, DateTimeType.DateTime);
                // TODO: enable user id
                //update.AddColumn("ModifyUserID", context.UserID);
                update.AddCondition(new SqlCondition("AID", taskId));
                if (prevStatusCondition != null)
                {
                    update.AddCondition(prevStatusCondition.ToString());
                }
            }

            System.Diagnostics.Debug.WriteLine(batch.ToString());

            int results = SqlDBHelper.ExecuteSql(batch.ToString());
            return results;
        }

        public bool CheckTask(CallContext context, int taskId, string checkMsg)
        {
            SqlUpdate update = new SqlUpdate("TT_Task");
            update.AddColumn("Status", (int)TaskStatus.Checked);
            update.AddColumn(new SqlExpression("CheckNote", checkMsg));
            update.AddColumn("ModifyDateTime", DateTime.Now, DateTimeType.DateTime);
            // TODO: enable user id
            //update.AddColumn("ModifyUserID", context.UserID);
            update.AddCondition(new SqlCondition("AID", taskId));

            AMS.DataAccess.SqlDebugger.WriteLine(update);

            return 0 < SqlDBHelper.ExecuteSql(update.ToString());
        }

        /// <summary>
        /// 取消审核任务
        /// </summary>
        /// <param name="context"></param>
        /// <param name="taskId"></param>
        /// <returns></returns>
        public bool CancelCheckTask(CallContext context, int taskId)
        {
            SqlUpdate update = new SqlUpdate("TT_Task");
            update.AddColumn("Status", (int)TaskStatus.Completed);
            update.AddColumnNullValue("CheckNote");
            update.AddColumn("ModifyDateTime", DateTime.Now, DateTimeType.DateTime);
            // TODO: enable user id
            //update.AddColumn("ModifyUserID", context.UserID);
            update.AddCondition(new SqlCondition("AID", taskId));

            AMS.DataAccess.SqlDebugger.WriteLine(update);

            return 0 < SqlDBHelper.ExecuteSql(update.ToString());
        }

        public int BatchCheckTask(CallContext context, int[] taskIDs, string checkMsg)
        {
            SqlBatch batch = new SqlBatch();
            DateTime now = DateTime.Now;

            foreach (int taskId in taskIDs)
            {
                SqlUpdate update = batch.CreateSqlUpdate("TT_Task");
                update.AddColumn("Status", (int)TaskStatus.Checked);
                update.AddColumn("CheckNote", checkMsg);
                update.AddColumn("ModifyDateTime", DateTime.Now, DateTimeType.DateTime);
                // TODO: enable user id
                //update.AddColumn("ModifyUserID", context.UserID);
                update.AddCondition(new SqlCondition("AID", taskId));
            }

            System.Diagnostics.Debug.WriteLine(batch.ToString());

            return SqlDBHelper.ExecuteSql(batch.ToString());
        }
    }
}

